home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Scene 96
/
Scene 96 International Edition (Zyklop Software) (Disc 2) (1997).iso
/
misc
/
coding
/
vgacodng
/
part01.txt
< prev
next >
Wrap
Text File
|
1996-08-07
|
10KB
|
202 lines
VGA-Kurs - Part #1
An alle, die sich schon ein bißchen mit Pascal und Assembler auskennen, und
nun unbedingt Spiele, Demos oder anderes in VGA coden möchten! Hier ist der
erste Teil von "T.C.P.'s Beginner's Guide To VGA Coding"(TM)!
(Anmerkung für alle erfahrenen Coder: Ihr müßt das hier natürlich nicht lesen,
da ihr das sowieso schon alles wißt, aber es kann ja nix schaden, gelle? Ach
so: Falls ich irgendwas falsch mache, könnt ihr mich natürlich berichtigen,
schließlich is ja nobody perfect!)
Wenn meine Annahme stimmt, daß viele Leute so was lesen wollen, werde ich
diese Serie fortsetzen, bekomme ich allerdings nicht genügend Resonanz, werde
ich das Schreiben einstellen.
Ich werde in den ersten Teilen die Grundlagen vermitteln und mich später, bei
genügend Resonanz wie gesagt, auch fortgeschritteneren Teilen der
VGA-Programmierung annehmen, wie Mode-X, Undokumentierte VGA-Funktionen,
Sprites, HiRes-Coding etc.
Na dann mal ran ans Eingemachte!
Wer Pascal hat, hat vielleicht schon mal ein bißchen mit BGIs rumgecodet.
Inzwischen gibt es zwar auch 256-Farben-BGIs aber trotzdem: Vergeßt es!
Diese Dinger taugen vielleicht für irgendwelche HiRes-Lame-O-Slow-Anwendungen,
für die man das Rad (sprich: SVGA-Routinen) nicht neu erfinden will, aber für
Spiele (geschweige denn Demos) - nej, nej, nej, da brauchts schon n' bisserl
mehr.
"Also, wie komme ich in den 256-Farben-VGA-Modus, ohne an BGIs auch nur einen
Gedanken zu verschwenden?" werdet ihr jetzt fragen. Die Antwort ist absolut
simpel: Inline Assembler! (Übrigens DAS Demo-Coder-Zauberwort schlechthin!)
Hier also eine Prozedur zum Initialisieren des 256-Farben-Modus:
procedure SetMCGAMode;assembler;
asm
mov ax,13h
int 10h
end;
Wie ja wohl jeder sehen kann, lädt diese Prozedur das AX-Reg mit 13h und ruft
den VGA-Bios-Interrupt 10h auf.
Die VGA-Karte weiß nun, daß sie in den Modus 13h (320x200 Pixel, 256 Farben)
schalten soll. Was lernen wir daraus? Wir schreiben in AX den Video-Modus,
den wir haben möchten, callen den INT 10h und -baff!- befinden wir uns im
gewünschten Modus. Die Nummer des Standard Textmodus ist übrigens 3h. Hier
eine kleine Übungsaufgabe für zu Hause: Wie komme ich zurück in den Textmodus?
Richtig! Wir ersetzen 13h durch 03h.
Den INT 10h sollte man sich übrigens gut merken, da er später sehr wichtig
werden wird.
So, schön und gut, ich bin im richtigen Modus, aber was jetzt? Beginnen wir
mit der simpelsten Operation im Grafikmodus: Das Setzen eines Pixels!
Zuerst einmal: Was hat ein Pixel für Eigenschaften? 1. X-Koordinate (0-319),
2. Y-Koordinate (0-199), 3. Farbe (0-255).
Moment mal! War da nicht die Rede von 320x200x256 und nicht 319x199x255?
Tja, das ist so: Der Computer fängt nicht bei 1 an zu zählen wie die meisten
von uns, sondern bei 0. Was also für uns 1 Dose Coke ist, ist für den
Prozessor 0 Dose Coke. Was für uns X-Koord 1 ist, ist für den Compi X-Koord 0.
Alles klar? Der erste Pixel in der obersten Zeile ist also für den Rechner
(0,0), der zweite (1,0), der dritte (2,0), usw. Und so wollen wir es hier in
Zukunft auch halten. Wenn man jetzt also solange weiter macht, bis man bei
Pixel (319,0) angekommen ist, geht man in die nächste Zeile und nach links.
Jetzt hat man Pixel (0,1). Das kann man immer weiter treiben, bis man bei
Pixel (319,199) angekommen ist. Jetzt kennt man jeden Pixel persönlich und
kann sie abends zum Essen einladen ;-).
Wie ihr wahrscheinlich schon bemerkt habt, werden Pixel-Koordinaten
folgendermaßen angegeben: (X-Wert,Y-Wert).
Damit ihr es euch besser vorstellen könnt, hier noch einmal bildlich:
X
0,0──────────> 319,0
│ :
│ :
Y │ :
│ :
│ :
V············
0,199 319,199
Mit der Farbe verhält es sich genauso. Versucht dieses um 1 verschobene
System zu verinnerlichen, weil ihr nicht drum herumkommen werdet.
So, puh (Schweiß-von-der-Stirn-wisch), das hätten wir, aber wie setze ich
jetzt einen Pixel?
Da hilft uns unser alter Freund, der INT 10h.
(Anmerkung für alle erfahrenen Coder: Keine Panik, wir werden auch noch die
Variante kennenlernen, die ohne das Bios auskommt.)
Hier also eine Prozedur, die einen Pixel an die gewünschte Stelle in der
gewünschten Farbe setzt:
procedure PutPixel(x,y:integer;col:byte);assembler;
asm
mov ah,0Ch
mov al,col
mov cx,x
mov dx,y
int 10h
end;
Will man also einen weißen (Farbe 31) Pixel an (55,120) setzen ruft man die
Prozedur mit
PutPixel(55,120,31);
auf. Dieser Befehl schreibt nun ins AH-Reg die Funktionsnummer, in AL die
gewünschte Farbnummer, in CX und DX die X- und Y-Koords. Anschließend wird
der INT 10h bemüht, die Arbeit zu übernehmen. Nun sehen wir im unteren linken
Viertel des Bildschirms einen weißen Punkt (vorrausgesetzt, wir befinden uns
im Modus 13h). Nun, dieses Wissen öffnet uns die Tore zu vielen kleinen
Spielereien, die ihr euch jetzt zu Hause ausdenken könnt. Wir könnten zum
Bleistift den gesamten Bildschirm mit Pixeln in beliebigen Farben zuknallen.
program FillScreen;
uses crt;
var n1,n2 : integer;
:
: (Hier stehen die oben
: besprochenen Prozeduren)
:
begin
randomize;
SetMCGAMode;
for n1 := 0 to 319 do
for n2 := 0 to 199 do PutPixel(n1,n2,random(256));
readkey;
SetTextMode;
end.
Schön, nich? Jetzt haben wir einen zugemüllerten Screen. Aber wie kriegen wir
ihn wieder leer? Ist schließlich nicht sooo schön auf Dauer!
Die ganz schlauen werden jetzt sagen: "Ist doch ganz einfach! Ich ersetze das
"random(256)" durch "0"!" Tja, auch ne Lösung, aber so einfach wollen wirs uns
nun auch nicht machen. Außerdem wäre diese Lösung viel zu langsam, und damit
so unbrauchbar wie ein MS-Produkt ;-). Also, hier die bessere (und schnellere)
Lösung:
procedure ClrVGA(col:byte);
begin
fillchar(mem[$A000:0],64000,col);
end;
Hier ausnahmsweise mal kein Assembler sondern ein Standard-Pascal-Befehl am
Werk. Er füllt den Speicherbereich ab A000h:0 (64000 Byte, hier blendet die
VGA ihren Bildschirmspeicher ein, 320 x 200 = 64000) mit der Farbnummer in
"Col" auf. Ihr könnt den Screen also in jeder beliebigen Farbe löschen, aber
am gebräuchlichsten ist wohl 0 (Schwarz).
Jetzt wo wir schon etwas mehr bewandelt sind, können wir uns der Verfeinerung
unseres Wissens widmen. Zum Beilpils: Warum ist unsere PutPixel-Prozedur so
langsam? Ganz einfach: Sie benutzt das Bios! Wenn wir mit dieser Prozedur ein
Spiel oder sogar ein Demo machen wollten, würden wir wahrscheinlich nicht
besonders weit kommen! Will man also wirklich geschwindigkeitsoptimiert coden,
muß man meistens einen anderen, unbequemeren Weg als das VGA-Bios benutzen.
In diesem Fall können wir die Prozedur erheblich beschleunigen, wenn wir die
Pixel-Daten direkt in den Bildschirmspeicher schreiben. Erinnert ihr euch?
Der Bildschirmspeicher im Modus 13h ist ein 64000(320x200)Byte großer
Speicherbereich an der Adresse A000h:0. In diesem Bereich stehen die
Farbwerte sämtlicher Pixel auf dem VGA-Screen. In den ersten 320 Byte stehen
also die Farbwerte aller Pixel der ersten VGA-Zeile hintereinander. Die
nächsten 320 Byte beinhalten die Werte der nächsten Zeile, usw. bis zum
letzten Pixel, dessen Farbwert an Adresse A000h:63999 steht. Da wir dies nun
wissen, können wir mit Hilfe der Formel
Byte-Adresse = 320 x Y-Koord + X-Koord
berechnen, welche Adresse welcher Pixel einnimmt. Hier also die optimierte
PutPixel-Routine:
procedure PutPixel(x,y:integer;col:byte);
begin
mem[$A000:320*y+x] := col;
end;
Wer diese Prozedur nun in unser "FillScreen"-Proggi einbaut, wird die
erhebliche Geschwindigkeitssteigerung bemerken. Aber es geht noch schneller!
Und zwar, indem man nie Prozedur in Assembler schreibt (War ja klar! ;-).
Aber das überlasse ich euch für zu Hause, schließlich sollt ihr auch mal
selber was machen. Geübte Coder können bestimmt noch ein paar Clocks
raushauen.
So, das wars dann fürs Erste von "T.C.P.'s Beginner's Guide To VGA
Coding"(TM)! Ich hoffe, es hat euch was gebracht, und ich bekomme reichlich
Feedback. Gebt auch eure Wünsche an, was ihr auf jeden Fall in einer der
Ausgaben besprochen sehen wollt. Ich schreibe diesen Kurs gerne, aber nur wenn
sich auch genug Leute dafür interessieren, sonst kann ich mir die Arbeit
sparen! Also, schreibt was!
[ This text copyright (c) 1995-96 Johannes Spohr. All rights reserved. ]
[ Distributed exclusively through PC-Heimwerker, Verlag Thomas Eberle. ]
[ ]
[ No part of this document may be reproduced, transmitted, ]
[ transcribed, stored in a retrieval system, or translated into any ]
[ human or computer language, in any form or by any means; electronic, ]
[ mechanical, magnetic, optical, chemical, manual or otherwise, ]
[ without the expressed written permission of the author. ]
[ ]
[ The information contained in this text is believed to be correct. ]
[ The text is subject to change without notice and does not represent ]
[ a commitment on the part of the author. ]
[ The author does not make a warranty of any kind with regard to this ]
[ material, including, but not limited to, the implied warranties of ]
[ merchantability and fitness for a particular purpose. The author ]
[ shall not be liable for errors contained herein or for incidental or ]
[ consequential damages in connection with the furnishing, performance ]
[ or use of this material. ]